package com.example.demo.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.example.demo.exception.ServiceException;
import com.example.demo.mapper.SysAttachinfoMapper;
import com.example.demo.model.entity.SysAttachinfo;
import com.example.demo.model.form.FileInfoForm;
import com.example.demo.service.SysAttachService;
import com.mybatisflex.core.query.QueryWrapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

/**
 * 本地存储服务类
 */
@Data
@Slf4j
@Component
@ConditionalOnProperty(value = "oss.type", havingValue = "local")
@ConfigurationProperties(prefix = "oss.local")
public class SysAttachLocalImplService implements SysAttachService {

    @Value("${oss.local.storage-path}")
    private String storagePath;
    @Autowired
    private SysAttachinfoMapper sysAttachinfoMapper;

    /**
     * 上传文件方法
     *
     * @param file 表单文件对象
     * @return 文件信息
     */
    @Override
    public FileInfoForm uploadFile(MultipartFile file) {
        // 获取文件名
        String originalFilename = file.getOriginalFilename();
        // 获取文件后缀
        String suffix = FileUtil.getSuffix(originalFilename);
        // 生成uuid
        String attachGuid = IdUtil.simpleUUID();
        String fileName = attachGuid + "." + suffix;

        // 生成文件名(日期文件夹)
        String filePrefix = storagePath.endsWith(File.separator) ? storagePath : storagePath + File.separator;
        //  try-with-resource 语法糖自动释放流
        try (InputStream inputStream = file.getInputStream()) {
            // 上传文件
            int length = inputStream.available();
            FileUtil.writeFromStream(inputStream, filePrefix  + File.separator + fileName);

            // 获取文件访问路径，因为这里是本地存储，所以直接返回文件的相对路径，需要前端自行处理访问前缀
            String fileUrl =  fileName;

            SysAttachinfo attachinfo = new SysAttachinfo();
            attachinfo.setAttachguid(attachGuid);
            attachinfo.setAttachfilename(originalFilename);
            attachinfo.setContenttype(file.getContentType());
            attachinfo.setAttachlength(length);
            attachinfo.setStoragetype("local");
            attachinfo.setUpdatetime(new Date());
            attachinfo.setFilepath(fileUrl);
            sysAttachinfoMapper.insert(attachinfo);

            FileInfoForm fileInfo = new FileInfoForm();
            fileInfo.setName(originalFilename);
            fileInfo.setUrl(fileUrl);
            fileInfo.setAttachGuid(attachGuid);
            return fileInfo;
        } catch (Exception e) {
            log.error("文件上传失败", e);
            throw new RuntimeException("文件上传失败");
        }

    }


    /**
     * 删除文件
     *
     * @param attachGuid 文件标识
     * @return 是否删除成功
     */
    @Override
    public boolean deleteFile(String attachGuid) {
        //判断文件是否为空
        if (StrUtil.isBlank(attachGuid)) {
            return false;
        }
        SysAttachinfo attachinfo = sysAttachinfoMapper.selectOneById(attachGuid);
        if(attachinfo == null) {
            return false;
        }
        sysAttachinfoMapper.deleteById(attachGuid);
        String filePrefix = storagePath.endsWith(File.separator) ? storagePath : storagePath + File.separator;
        String suffix = FileUtil.getSuffix(attachinfo.getAttachfilename());
        String fileName = attachGuid + "." + suffix;
        // 删除文件
        return FileUtil.del(filePrefix  + File.separator + fileName);
    }

    @Override
    public InputStream downloadFile(String attachGuid) {
        SysAttachinfo attachinfo = sysAttachinfoMapper.selectOneById(attachGuid);
        if(attachinfo == null) {
            throw new ServiceException("文件不存在，附件标识 "+ attachGuid);
        }
        String filePrefix = storagePath.endsWith(File.separator) ? storagePath : storagePath + File.separator;
        String suffix = FileUtil.getSuffix(attachinfo.getAttachfilename());
        String fileName = attachGuid + "." + suffix;
        try {
            return new FileInputStream(filePrefix  + File.separator + fileName);
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void updateFileClientinfo(List<String> attachGuidList, String clientGuid) {
        List<SysAttachinfo> attachList = sysAttachinfoMapper.selectListByQuery(QueryWrapper.create().in("attachguid", attachGuidList));
        for (SysAttachinfo attachinfo : attachList) {
            attachinfo.setClientguid(clientGuid);
            sysAttachinfoMapper.update(attachinfo);
        }
    }

    @Override
    public void updateFileClientinfo(List<String> attachGuidList, String clientGuid, String clientTag) {
        List<SysAttachinfo> attachList = sysAttachinfoMapper.selectListByQuery(QueryWrapper.create().in("attachguid", attachGuidList));
        for (SysAttachinfo attachinfo : attachList) {
            attachinfo.setClientguid(clientGuid);
            attachinfo.setClienttag(clientTag);
            sysAttachinfoMapper.update(attachinfo);
        }
    }
}
